/***********************************************************************************************************************
	Fichier: Jeu.c
	Ensemble des fonctions nécessaires pour pouvoir jouer au tetris,commune aux deux interfaces: graphique et texte.
*************************************************************************************************************************/
#include "Jeu.h"

Jeu * JeuCreer()
{
	Jeu * sortie = (Jeu*)malloc(sizeof(Jeu));/* on alloue de la mémoire pour la structure Jeu */
	return sortie;
}


void JeuDetruire(Jeu * j)
{
	FormeDetruirePiece(j->suivante);/* on libère d'abord le champ suivant  */
	TerrainDetruire(j->terrain);/* on libère ensuite le champ terrain */
	if ( j->etat == PERDU ) 
	{
		FormeDetruirePiece(j->tombe);/* on libère le champs tombe, si l'état est PERDU */
	}
	free(j);/* Et enfin on libère la mémoire alloué pour Jeu  */
}

void JeuInitialiser(Jeu * j)
{
	srand(time(NULL));  /* on initialise le générateur de nombres pseudo-aléatoires */
	j->terrain = TerrainCreer(); /* on crée le terrain  */
	TerrainInitialiser((j->terrain)); /* et on l'initialise */

	j->suivante = FormeCreerPiece(); /* on crée la 1ere piece  */
	j->tombe = NULL; /* et on indique qu'aucune autre piece n'est en chute*/

	Couleur c = ((Couleur)(rand()%COULEUR_MAX)); /* on tire au hasard la couleur et la forme de la première piece*/
	FormeInitialiserPiece((j->suivante), c + 1, Formes[(int)c]); /* et on et on initialise la premiere piece*/
	j->score = 0; /* le score en début de partie est nulle*/
	j->niveau = 1; /* on commence au premier niveau*/
	j->etat = MENU;/* pour l'instant le jeu n'est pas commencé, nous sommes dans MENU */
}



void JeuAffichage(Jeu * j)
{
	printf("\nTerrain : \n");
	TerrainAfficher((j->terrain));
	printf("\nForme suivante : \n");
	FormeAfficherPiece((j->suivante));
	printf("\nForme qui tombe: \n");

	FormeAfficherPiece((j->tombe));
	printf("\nScore : %d\n",j->score);
	printf("\nNiveau : %d\n",j->niveau);
	printf("\nEtat : %d\n",(int) j->etat);
}



int  JeuActionClavier(Jeu * j, const char touche)
{
	switch(touche)
	{
	 case 'g': return TerrainDeplacerPiece((j->tombe), (j->terrain), GAUCHE);/* Déplace la pièce à gauche */
		break;

	case 'd': return TerrainDeplacerPiece((j->tombe), (j->terrain), DROITE);/* Déplace la pièce à droite  */
		break;

	case 'b': return TerrainDeplacerPiece((j->tombe),(j->terrain), BAS);/* Déplace la pièce vers le bas */
		break;

	case 'p': return TerrainRotation((j->tombe),(j->terrain));/* Fait tourner la pièce ' */
		break;
	default: return 0;
		break;
	}
}

int JeuEffacerLignesPleine(Jeu * j)
{
	int lignesaeffacer[TAILLE_Y] = {0};
	int i;
	int nbr_lignes = TerrainChercherLignePleine(j->terrain, (int*)&lignesaeffacer); /* on cherche les lignes pleines*/
		for ( i = 0 ; i < nbr_lignes ; i++) /* pour chaque ligne pleine */
		{
			TerrainSupprimerLigne(j->terrain, (int)lignesaeffacer[i]); /* on efface les lignes une par une */
		}
		j->score += j->niveau * (nbr_lignes*nbr_lignes*10); /* et on augmente le score suivant le nombre de ligne supprimé */
		if ( j->score > ( (j->niveau*(j->niveau)*50) ) )
		{
			/* si le score est assez haut on augmente le niveau */
			j->niveau++;
		}
	return (nbr_lignes != 0);
}


void JeuNouvellePiece(Jeu * j)
{
	j->tombe = j->suivante;/* on met la pièce suivante dans la pièce tombe */
	j->suivante = FormeCreerPiece();/* on crée une nouvelle pièce dans la pièce suivante */
	Couleur c;
	c = ((Couleur)(rand()%COULEUR_MAX)); /* on choisit une couleur au hasard pour initialiser la pièce suivante */
	FormeInitialiserPiece((j->suivante), c + 1, Formes[(int)c]);
	if ( TerrainAjouterPiece(j->terrain, j->tombe) == 0 )
	 {
		j->etat = PERDU; /* si on ne peux pas ajouter de pièce avec la nouvelle pièce tombe on modifie l'état du jeu */
	 }

}


int JeuFaireTomberToutesPieces(Jeu * j)
{
	return TerrainAppliquerPesanteur(j->terrain);
}


void JeuSetEtat(Jeu * j, EtatPartie e)
{
	 j->etat = e;
}

EtatPartie JeuGetEtat(Jeu * j)
{
	return j->etat;
}

int JeuGetScore(Jeu * j)
{
	return j->score;
}


Terrain* JeuGetTerrain(Jeu * j)
{
	return j->terrain;
}

Piece* JeuGetSuivante(Jeu * j)
{
	return j->suivante;
}


int JeuGetNiveau(Jeu * j)
{
	return j->niveau;
}


void JeuRelancer(Jeu * j)
{

	TerrainDetruire(j->terrain);/* on libère le terrain en cours */
	j->terrain = TerrainCreer();/* on crée un nouveau terrain */
	TerrainInitialiser((j->terrain)); /* on l'initialise à 0 */
	FormeDetruirePiece(j->suivante);/* on libère la pièce suivante */
	j->suivante = FormeCreerPiece(); /* on crée la piece qui tombera en premier */
	FormeDetruirePiece(j->tombe);/* on libère la pièce qui tombe */
	j->tombe = NULL; /* et on indique qu'aucune piece n'est en chute*/
	Couleur c = ((Couleur)(rand()%COULEUR_MAX)); /* on tire au hazard la couleur et la forme de la premiere piece */
	FormeInitialiserPiece((j->suivante), c + 1, Formes[(int)c]); /* et on et on initialise la premiere piece */
	j->score = 0; /* le score en début de partie est 0 */
	j->niveau = 1; /* on commence au premier niveau */
	j->etat = JEU;/* le jeu est en cours */
}
